#ifndef AI_HEADER
#define AI_HEADER

#include <vector>
#include <list>
#include <map>
#include "GameEntity.h"
#include "../../Dependencies.h"

typedef int array2d[7][5];
typedef int array1d[5];
//typedef int array2d[10][10];
//typedef int array1d[10];


class AI : public GameEntity {
public:
	AI(int, std::string);								//Constructor with frequency to initialize updatable 
														//and String to initialize name of the Game Entity
	virtual ~AI();										//Destructor
	virtual void draw() = 0;							//For drawing
	virtual void actualUpdate(unsigned long long timePassed) = 0;		//For updating
	virtual void reset() = 0;							//For resetting
	virtual int getType() = 0;							//For getting the entity type

protected:
	std::vector<int> moveActions;						//The vector of all move actions the artificial entity can perform
	std::vector<int> miscellActions;					//The vector of all miscellaneous actions the artificial entity can perform
	std::list<int> plan;								//The plan of the artificial entity

	void doSomething();
	virtual void sense() = 0;							//Sense the environment
	virtual void reason() = 0;							//Reason about the situation
	virtual void act(int action) = 0;					//Do an action (out of possibleActions)

	//for our hillclimbing algorithm
	int bestImprovement();								//Do the action that gives the best (local) improvement
	int firstImprovement();								//Do the action that gives the first (local) improvement
	virtual float evaluate(POINT3D) = 0;				//Evaluate a situation

	//For our distancemap-based path planning algorithm
	void planPath(array1d *);							//Plan a path using a distance map
	void createDistanceMap(POINT3D, array1d *);			//Creates a distancemap towards some goal
	void addToFront(POINT3D,int, array1d *, std::vector<POINT3D> *);//Add all points that are reachable from a certain position	
	virtual POINT3D simulateMove(POINT3D, int) = 0;		//simulates a move(it returns the new position after a certain action is done on an old position)	

private:
	std::vector<POINT3D> front;
	std::vector<POINT3D> newFront;
};

#endif